package com.example.statistics.ex

import android.app.Activity
import android.content.Context
import android.view.Gravity
import android.view.View
import com.example.statistics.utils.AreaUtil
import com.example.statistics.utils.Constants
import com.jhj.imageselector.utils.toArrayList
import com.jhj.prompt.fragment.AlertFragment
import com.jhj.prompt.fragment.LoadingFragment
import com.jhj.prompt.fragment.OptionsFragment
import com.jhj.prompt.fragment.PercentFragment
import com.jhj.prompt.fragment.base.OnDialogShowOnBackListener
import com.jhj.prompt.fragment.options.interfaces.OnOptionsSelectedListener
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext


fun Context.areaList(body: (ArrayList<AreaUtil.AreaNode>, ArrayList<ArrayList<AreaUtil.AreaNode>>, ArrayList<ArrayList<ArrayList<AreaUtil.AreaNode>>>) -> Unit) {
    GlobalScope.launch {
        val areaList = AreaUtil.getAreaList(this@areaList)
        val provinceList = areaList.filter { it.areaDeep == 1 }.toArrayList()
        val cityList = provinceList.map { provinceBean ->
            areaList.filter { it.areaDeep == 2 && it.areaParentId == provinceBean.areaId }.toArrayList()
        }.toArrayList()
        val districtList = cityList.map { cityList ->
            cityList.map { cityBean ->
                areaList.filter { it.areaDeep == 3 && it.areaParentId == cityBean.areaId }.toArrayList()
            }.toArrayList()
        }.toArrayList()
        withContext(Dispatchers.Main) {
            body(provinceList, cityList, districtList)
        }
    }
}

fun Context.areaDialog(
    o1: Int = 0,
    o2: Int = 0,
    o3: Int = 0,
    body: (AreaUtil.AreaNode, AreaUtil.AreaNode, AreaUtil.AreaNode) -> Unit
) {
    val areaList = AreaUtil.getAreaList(this)
    GlobalScope.launch {
        val provinceList = areaList.filter { it.areaDeep == 1 }.toArrayList()
        val cityList = provinceList.map { provinceBean ->
            areaList.filter { it.areaDeep == 2 && it.areaParentId == provinceBean.areaId }.toArrayList()
        }.toArrayList()
        val districtList = cityList.map { cityList ->
            cityList.map { cityBean ->
                areaList.filter { it.areaDeep == 3 && it.areaParentId == cityBean.areaId }.toArrayList()
            }.toArrayList()
        }.toArrayList()
        withContext(Dispatchers.Main) {
            OptionsFragment.Builder<AreaUtil.AreaNode>(this@areaDialog)
                .setLinkedPicker(provinceList, cityList, districtList)
                .setSelectOptions(o1, o2, o3)
                .setSubmitListener(object : OnOptionsSelectedListener<AreaUtil.AreaNode> {
                    override fun onOptionsSelect(
                        options: OptionsFragment<AreaUtil.AreaNode>,
                        options1: Int?,
                        options2: Int?,
                        options3: Int?
                    ) {
                        val province = provinceList[options1.orEmpty()]
                        val city = cityList[options1.orEmpty()][options2.orEmpty()]
                        val area = districtList[options1.orEmpty()][options2.orEmpty()][options3.orEmpty()]
                        body(province, city, area)
                    }
                })
                .show()
        }
    }
}

fun Context.customDialog(layoutRes: Int, body: (View, AlertFragment) -> Unit) {
    AlertFragment.Builder(this)
        .setCustomLayoutRes(layoutRes, object : AlertFragment.OnCustomListener {
            override fun onLayout(alert: AlertFragment, view: View) {
                body(view, alert)
            }
        })
        .show()
}

fun Context.bottomCustomDialog(layoutRes: Int, body: (View, AlertFragment) -> Unit): AlertFragment.Builder {
    return AlertFragment.Builder(this)
        .setMarginHorizontal(0)
        .setMarginBottom(0)
        .setDialogGravity(Gravity.BOTTOM)
        .setCustomLayoutRes(layoutRes, object : AlertFragment.OnCustomListener {
            override fun onLayout(alert: AlertFragment, view: View) {
                body(view, alert)
            }
        })
        .show()
}


fun Context.bottomSingleDialog(
    title: String = "请选择",
    gravity: Int = Gravity.BOTTOM,
    list: List<String>,
    body: (AlertFragment, String) -> Unit
) {
    AlertFragment.Builder(this)
        .setDataList(list.toArrayList())
        .setDialogGravity(gravity)
        .setDialogBottomSeparate(true)
        .setTitle(title)
        .setItemClickedListener(object : AlertFragment.OnItemClickListener {
            override fun onItemClick(alert: AlertFragment, view: View, position: Int) {
                body(alert, list[position])
            }
        })
        .setCancelListener(object : AlertFragment.OnButtonClickedListener {
            override fun onClick(alert: AlertFragment, view: View?) {

            }
        })
        .show()
}

fun Context.bottomMultiDialog(
    title: String = "请选择",
    list: List<String>,
    selectedList: List<Int>,
    body: (AlertFragment, List<Int>) -> Unit
) {
    AlertFragment.Builder(this)
        .setSelectedDataList(list.toArrayList())
        .setSelectedItem(selectedList.toArrayList())
        .setDialogGravity(Gravity.BOTTOM)
        .setDialogBottomSeparate(true)
        .setTitle(title)
        .setListSelectedListener(object : AlertFragment.OnItemSelectedListener {
            override fun onSelected(alert: AlertFragment, selectedList: List<Int>) {
                body(alert, selectedList)
            }
        })
        .show()
}

fun Context.percentUploadDialog(msg: String = "正在上传...", body: (PercentFragment) -> Unit): PercentFragment.Builder {
    return PercentFragment.Builder(this)
        .setText(msg)
        .setDialogShowOnBackListener(object : OnDialogShowOnBackListener<PercentFragment> {
            override fun cancel(fragment: PercentFragment) {
                body(fragment)
            }
        })
        .setCancelOnTouchOut(false)
        .show()
}

fun Context.uploadDialog(msg: String = "正在上传...", body: (LoadingFragment) -> Unit): LoadingFragment.Builder {
    return LoadingFragment.Builder(this)
        .setText(msg)
        .setCancelOnTouchOut(false)
        .setDialogShowOnBackListener(object : OnDialogShowOnBackListener<LoadingFragment> {
            override fun cancel(fragment: LoadingFragment) {
                body(fragment)
            }
        })
        .show()
}


fun Context.loadingDialog(text: String = "正在加载...", body: (LoadingFragment) -> Unit = {}): LoadingFragment.Builder {
    return LoadingFragment.Builder(this)
        .setText(text)
        .setCancelOnTouchOut(false)
        .setDialogShowOnBackListener(object : OnDialogShowOnBackListener<LoadingFragment> {
            override fun cancel(fragment: LoadingFragment) {
                if (this@loadingDialog is Activity) {
                    this@loadingDialog.finish()
                }
                body(fragment)
            }
        })
        .show()
}

fun Context.messageDialog(title: String = "提示", msg: String, body: (AlertFragment, View?) -> Unit = { _, _ -> }) {
    AlertFragment.Builder(this)
        .setTitle(title)
        .setMessage(msg)
        .setSubmitListener(object : AlertFragment.OnButtonClickedListener {
            override fun onClick(alert: AlertFragment, view: View?) {
                body(alert, view)
            }
        })
        .setCancelListener(object : AlertFragment.OnButtonClickedListener {
            override fun onClick(alert: AlertFragment, view: View?) {

            }
        })
        .show()
}


fun Context.singleDialog(vararg strings: String, body: (String) -> Unit) {
    val dialogDataList = arrayListOf<String>()
    strings.forEach {
        dialogDataList.add(it)
    }
    singleDialog(dialogDataList, strings.toList(), body)
}


fun <T : IDialogModel> Context.singleDialog(vararg ts: T, body: (T) -> Unit) {
    val dialogDataList = arrayListOf<String>()
    ts.forEach {
        dialogDataList.add(it.itemName)
    }
    singleDialog(dialogDataList, ts.toList(), body)
}

fun <T : IDialogModel> Context.singleDialog(dialogDataList: List<T>?, body: (T) -> Unit) {
    if (dialogDataList.isNullOrEmpty()) return
    val list = arrayListOf<String>()
    dialogDataList.forEach {
        list.add(it.itemName)
    }
    singleDialog(list, dialogDataList, body)
}

private fun <T> Context.singleDialog(list: ArrayList<String>, str: List<T>, body: (T) -> Unit) {
    AlertFragment.Builder(this)
        .setDataList(list)
        .setDialogGravity(Gravity.BOTTOM)
        .setDialogBottomSeparate(true)
        .setTitle("请选择")
        .setItemClickedListener(object : AlertFragment.OnItemClickListener {
            override fun onItemClick(alert: AlertFragment, view: View, position: Int) {
                body(str[position])
            }
        })
        .setCancelListener(object : AlertFragment.OnButtonClickedListener {
            override fun onClick(alert: AlertFragment, view: View?) {

            }
        })
        .show()
}

/*inline fun <reified T> Context.actionDialog(vararg pairs: Pair<T, (T) -> Unit>) {
    if (pairs.isEmpty()) {
        throw Exception("action can't null")
    }
    val list = when (pairs.first().first) {
        is String -> {
            pairs.map { it.first.toString() }
        }
        is IDialogModel -> {
            pairs.map { (it.first as IDialogModel).itemName }
        }
        else -> {
            throw Exception("only support String::class and IDialogModel interface")
        }
    }

    actionDialog(list, pairs)
}*/

fun Context.actionDialog(vararg pairs: Pair<String, (String) -> Unit>) {
    val dialogDataList = pairs.map { it.first }
    actionDialog(dialogDataList, pairs)
}

fun <T : IDialogModel> Context.actionTDialog(vararg pairs: Pair<T, (T) -> Unit>) {
    val dialogDataList = pairs.map { it.first.itemName }
    actionDialog(dialogDataList, pairs)
}

private fun <T> Context.actionDialog(list: List<String>, pairs: Array<out Pair<T, (T) -> Unit>>) {
    AlertFragment.Builder(this)
        .setDataList(list.toArrayList())
        .setDialogGravity(Gravity.BOTTOM)
        .setDialogBottomSeparate(true)
        .setTitle("请选择")
        .setItemClickedListener(object : AlertFragment.OnItemClickListener {
            override fun onItemClick(alert: AlertFragment, view: View, position: Int) {
                pairs[position].second.invoke(pairs[position].first)
            }
        })
        .setCancelListener(object : AlertFragment.OnButtonClickedListener {
            override fun onClick(alert: AlertFragment, view: View?) {

            }
        })
        .show()
}

interface IDialogModel : java.io.Serializable {
    val itemName: String
}